<template>
  <a-modal v-model:visible="msgBox.visible" @ok="msgBox.handleOk" @cancel="msgBox.handleCancel"
           :hide-cancel="msgBox.hideCancel">
    <template #title>
      {{ msgBox.title }}
    </template>
    <div>{{ msgBox.msg }}
    </div>
  </a-modal>
  <a-modal v-model:visible="passwordReset.visible" @ok="passwordReset.handleOk" @cancel="passwordReset.handleCancel"
           @before-close="passwordReset.password = ''"
           :hide-cancel="true">
    <template #title>
      重置密码-[<span style="color: rgb(var(--link-6))">{{ passwordReset.username }}</span>]
    </template>
    <div style="width: 100%; text-align: center">
      <a-space>
        <span style="font-size: 0.9em"> 新密码为: </span>

        <span class="new_password">{{ passwordReset.password }}</span>
      </a-space>
    </div>

  </a-modal>
  <a-modal v-model:visible="addUser.visible" @before-close="() => this.addUser.model ={}"
           :mask-closable="false" :footer="false" :hide-cancel="true">
    <template #title>
      添加用户
    </template>
    <div>
      <a-form :model="addUser.model" :label-col-props="{span: 1, offset: 0}"
              @submit-success="createUser">
        <a-form-item field="username"
                     :rules="[{required:true,message:'用户名不能为空'},{minLength:1,maxLength:16,message:'1~16个字符'},{validator:numericLetters}]"
                     :validate-trigger="['change','input']" size="large" title="用户名">
          <a-input
              v-model="addUser.model.username" :max-length="16"
              placeholder="用户名" allow-clear
          >
            <template #prefix>
              <icon-user/>
            </template>
          </a-input>
          <template #extra>
            <div>1~16个字符,中文数字字母或者下划线</div>
          </template>
        </a-form-item>
        <a-form-item field="account" title="账号"
                     :rules="[{required:true,message:'账号不能为空'},{minLength:4,maxLength:16,message:'4~16个字符'},{validator:numericLetters}]"
                     :validate-trigger="['change','input']" size="large">
          <a-input
              v-model="addUser.model.account" :max-length="16" allow-clear
              placeholder="账号"
          >
            <template #prefix>
              <icon-idcard/>
            </template>
          </a-input>
          <template #extra>
            <div>4~16个字符,数字字母或者下划线,创建后不可更改</div>
          </template>
        </a-form-item>
        <a-form-item field="password" title="密码"
                     :rules="[{required:true,message:'密码不能为空'},{minLength:6,maxLength:16, message:'6~16个字符'},{validator:validatePassword}]"
                     :validate-trigger="['change','input']" size="large">
          <a-input-password
              v-model="addUser.model.password" :max-length="16"
              placeholder="密码" allow-clear
          >
            <template #prefix>
              <icon-lock/>
            </template>
          </a-input-password>
          <template #extra>
            <div>6~16个字符,仅含且必须含有数字和字母以及在"!@#$%^&*?"中的特殊字符</div>
          </template>
        </a-form-item>
        <a-form-item field="remark"
                     :rules="[{maxLength:255, message:'0~255个字符'}]"
                     :validate-trigger="['change','input']" size="large">
          <a-textarea placeholder="备注" allow-clear v-model="addUser.model.remark"
                      :auto-size="{ minRows:2, maxRows:5 }" show-word-limit :max-length="255"
          >

          </a-textarea>
        </a-form-item>
        <a-form-item>
          <a-button html-type="submit" type="primary">
            确定
          </a-button>
        </a-form-item>
      </a-form>
    </div>

  </a-modal>
  <a-modal v-model:visible="updateUser.visible" @before-close="() => this.updateUser.model ={}"
           :mask-closable="false" :footer="false" :hide-cancel="true">
    <template #title>
      修改用户
    </template>
    <div>
      <a-form :model="updateUser.model" :label-col-props="{span: 4, offset: 0}"
              @submit-success="updateUser_">
        <a-form-item field="username"
                     :rules="[{required:true,message:'用户名不能为空'},{minLength:1,maxLength:16,message:'1~16个字符'},{validator:numericLetters}]"
                     :validate-trigger="['change','input']" size="large" title="用户名" label=" 用户名">
          <a-input
              v-model="updateUser.model.username" :max-length="16"
              placeholder="用户名" allow-clear
          >
            <template #prefix>
              <icon-user/>
            </template>
          </a-input>
          <template #extra>
            <div>1~16个字符,中文数字字母或者下划线</div>
          </template>
        </a-form-item>
        <a-form-item field="remark"
                     :rules="[{maxLength:255, message:'0~255个字符'}]"
                     :validate-trigger="['change','input']" size="large" label="备注">
          <a-textarea placeholder="备注" allow-clear v-model="updateUser.model.remark"
                      :auto-size="{ minRows:2, maxRows:5 }" show-word-limit :max-length="255"
          >

          </a-textarea>
        </a-form-item>
        <a-form-item>
          <a-button html-type="submit" type="primary">
            确定
          </a-button>
        </a-form-item>
      </a-form>
    </div>

  </a-modal>
  <a-table :columns="columns" :data="userList" :row-selection="selectModel" summary>
    <template #enable="{ record ,rowIndex }">
      <a-switch
          checked-color="rgb(var(--blue-4)"
          unchecked-color="rgb(var(--gray-4)" :model-value="record.enable" @change="changeStatus(record ,rowIndex)"/>
    </template>
    <template #admin="{ record }">
      <icon-check size="large" v-if="record.admin" style="color: rgb(var(--success-6))"/>
      <icon-close size="large" v-else style="color: rgb(var(--danger-6))"/>
    </template>
    <template #locked="{  record ,rowIndex}">
      <a-button size="small" @click="unlock(record.account,rowIndex)" :status="record.locked ? 'warning':'success'"
                :title="record.locked ? '解锁':'未锁定'">
        <template #icon>
          <icon-lock v-if="record.locked"/>
          <icon-unlock v-else/>
        </template>
      </a-button>
    </template>
    <template #summary-cell="{ column }">
      <span v-if="column.dataIndex === 'username'">
       <a-button size="small" @click="newLine">
       <template #icon>
       <icon-plus/>
      </template></a-button>
      </span>
    </template>
    <template #optional="{record}">
      <a-space>
        <a-button status="warning"
                  @click="this.updateUser.model = Object.assign({}, record);this.updateUser.visible = true; ">
          <template #icon>
            <icon-edit/>
          </template>
        </a-button>
        <a-button status="danger" v-if="!record.admin" @click="deleteUser(record.account)">
          <template #icon>
            <icon-delete/>
          </template>
        </a-button>
        <a-button status="warning" v-if="!record.admin" @click="resetPassword(record.account, record.username)">
          重置密码
        </a-button>
      </a-space>
    </template>
    <template #name-filter="{ filterValue, setFilterValue, handleFilterConfirm, handleFilterReset}">
      <div class="custom-filter">
        <a-space direction="vertical">
          <a-input :model-value="filterValue[0]" @input="(value)=>setFilterValue([value])"/>
          <div class="custom-filter-footer">
            <a-button @click="handleFilterConfirm">确定</a-button>
            <a-button @click="handleFilterReset">重置</a-button>
          </div>
        </a-space>
      </div>
    </template>
  </a-table>
</template>
<script>
import {h} from "vue";
import {
  IconCheck,
  IconClose, IconDelete, IconEdit,
  IconIdcard,
  IconLock,
  IconPlus,
  IconSearch,
  IconUnlock,
  IconUser,
} from "@arco-design/web-vue/es/icon";
import {get, getPK, postPK} from "@/js/axios_util";
import {Message} from "@arco-design/web-vue";
import {doExchangeByCachePk, aesDecrypt} from "@/js/dh";
import {getUserError} from "@/js/error_code";
import {numericLetters, validatePassword} from "@/js/validator";

const voidFunction = () => {
};

export default {
  name: "user",
  components: {
    IconEdit, IconDelete, IconPlus, IconLock, IconUnlock, IconCheck, IconClose, IconUser, IconIdcard
    ,
  },
  data() {
    return {
      columns: [
        {
          title: '用户名',
          dataIndex: 'username',
          slotName: 'username',
          filterable: {
            filter: (value, record) => record.username.includes(value),
            slotName: 'name-filter',
            icon: () => h(IconSearch)
          }
        },
        {
          title: '账号',
          dataIndex: 'account',
          slotName: 'account'
        },
        {
          title: '启用状态',
          dataIndex: 'enable',
          slotName: 'enable'
        },
        {
          title: '锁定状态',
          dataIndex: 'locked',
          slotName: 'locked'
        },
        {
          title: '管理员权限',
          dataIndex: 'admin',
          slotName: 'admin'
        },
        {
          title: '最后登录时间',
          dataIndex: 'lastLoginTime',
          slotName: 'lastLoginTime'
        },
        {
          title: '最后登录IP',
          dataIndex: 'lastLoginIp',
          slotName: 'lastLoginIp'
        },
        {
          title: '备注',
          dataIndex: 'remark',
          slotName: 'remark'
        },
        {
          title: '操作',
          slotName: 'optional',
          fixed: 'right',
        }

      ],
      userList: [],
      selectModel: {
        type: 'checkbox',
        showCheckedAll: true
      },
      addUser: {
        visible: false,
        model: {}
      }, updateUser: {
        visible: false,
        model: {}
      }, msgBox: {
        visible: false,
        title: "Title",
        msg: "none",
        hideCancel: false
      }, passwordReset: {
        visible: false,
        password: "",
        username: "none",
      }
    }
  }, methods: {
    numericLetters,
    validatePassword,
    listUser() {
      get('/user/list', (response) => {
        this.userList = response.data;
      })
    }, showMsgBox(title, msg, ok, cancel) {
      if (msg === null) {
        return
      }
      this.msgBox.handleOk = ok ? ok : voidFunction;
      this.msgBox.handleCancel = cancel ? cancel : voidFunction;
      this.msgBox.title = title ? title : "Tip";
      this.msgBox.msg = msg;
      this.msgBox.visible = true;
    }, showNewPassword(username, password) {
      if (password === null) {
        return
      }
      this.passwordReset.handleOk = voidFunction
      this.passwordReset.handleCancel = voidFunction;
      this.passwordReset.username = username
      this.passwordReset.password = password;
      this.passwordReset.visible = true
    }, newLine() {
      this.addUser.visible = true;
    }, unlock(account, rowIndex) {
      doExchangeByCachePk((keyAgreeResult, aesEncode) => {

        let secret = keyAgreeResult.secret;
        let account1 = aesEncode(account, secret, 'hex');
        getPK('/user/unlockUser?account=' + account1, keyAgreeResult
            , resp => {
              let data = resp.data;
              if (data.success) {
                this.userList[rowIndex].locked = false;
                return
              }
              const reason = getUserError(data.statusCode);
              Message.error({content: `操作失败[${reason}]`, showIcon: true})
            })
      })
    }, changeStatus(user, index) {
      doExchangeByCachePk((keyAgreeResult, aesEncode) => {
        let secret = keyAgreeResult.secret;
        let account1 = aesEncode(user.account, secret, 'hex');
        let enable = !user.enable;
        getPK('/user/changeUserStatus?account=' + account1 + '&status=' + enable, keyAgreeResult
            , resp => {
              let data = resp.data;
              if (data.success) {
                this.userList[index].enable = enable;
                return
              }
              const reason = getUserError(data.statusCode);
              Message.error({content: `操作失败[${reason}]`, showIcon: true})
            })
      })
    }, createUser() {
      doExchangeByCachePk((keyAgreeResult, aesEncode) => {
        let model = this.addUser.model;
        let secret = keyAgreeResult.secret;
        let addUserData = {
          username: aesEncode(model.username, secret),
          account: aesEncode(model.account, secret),
          password: aesEncode(model.password, secret),
          remark: model.remark
        }

        postPK('/user/addUser', addUserData, keyAgreeResult
            , resp => {
              let data = resp.data;
              if (data.success) {
                this.addUser.visible = false;
                this.addUser.model = {};
                this.listUser();
                return
              }
              const reason = getUserError(data.statusCode);
              Message.error({content: `操作失败[${reason}]`, showIcon: true})

            })
      })
    }, updateUser_() {
      doExchangeByCachePk((keyAgreeResult, aesEncode) => {
        let model = this.updateUser.model;
        let secret = keyAgreeResult.secret;
        let updateUserData = {
          username: aesEncode(model.username, secret),
          account: aesEncode(model.account, secret),
          remark: model.remark
        }

        postPK('/user/updateUser', updateUserData, keyAgreeResult,
            resp => {
              let data = resp.data;
              if (data.success) {
                this.updateUser.visible = false;
                this.updateUser.model = {};
                this.listUser();
                return
              }
              const reason = getUserError(data.statusCode);
              Message.error({content: `操作失败[${reason}]`, showIcon: true})
            })
      })

    }, deleteUser(account) {
      this.showMsgBox("确定", "确定删除", () => {
        doExchangeByCachePk((keyAgreeResult, aesEncode) => {
          let secret = keyAgreeResult.secret;
          let account1 = aesEncode(account, secret, 'hex');
          getPK('/user/deleteUser?account=' + account1, keyAgreeResult
              , resp => {
                let data = resp.data;
                if (data.success) {
                  this.listUser();
                  return
                }
                const reason = getUserError(data.statusCode);
                Message.error({content: `操作失败[${reason}]`, showIcon: true})
              })
        })
      })


    }, resetPassword(account, username) {
      this.showMsgBox("确定", `确定是否重置${username}的密码?`, () => {
            doExchangeByCachePk((keyAgreeResult, aesEncode) => {

              let secret = keyAgreeResult.secret;
              let account1 = aesEncode(account, secret, 'hex');
              getPK('/user/resetPassword?account=' + account1, keyAgreeResult
                  , resp => {
                    let data = resp.data;
                    if (data.success) {
                      let password = aesDecrypt(data.result, secret)
                      this.showNewPassword(username, password)
                      return
                    }
                    const reason = getUserError(data.statusCode);
                    Message.error({content: `操作失败[${reason}]`, showIcon: true})
                  })
            })
          }
      )
    }
  },
  created() {
    this.listUser()
  }
}
</script>
<style>
.new_password {
  background: rgba(var(--blue-5), 0.2);
  color: rgb(var(--orange-6));
  padding-left: 0.5em;
  padding-right: 0.5em;
  display: inline-block;
  font-style: italic;
  font-size: 1.2em;
}
</style>